package com.iplatform.iplatformuser.framework.privilege.util;

import com.iplatform.iplatformuser.framework.privilege.bean.GroupResourceBean;
import com.iplatform.iplatformuser.framework.privilege.dialect.Dialect;
import com.iplatform.iplatformuser.framework.privilege.dialect.OracleBoundsDialect;
import com.github.pagehelper.util.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Title: FilterBoundSqlUtil
* Description:   数据权限过滤工具类
* SQL语句的要求
* 1.别名需要加上 as
* 2.资源关键别名  org_id , spec_id
* 3.v1.0暂未处理PageHelper
* @author RayLLi
* @date 2019年6月20日
 */
public class FilterBoundSqlUtil {

	public FilterBoundSqlUtil() {}

	/**
	 * 使用工具类的时候存储用户资源信息
	* Title:
	* Description:
	* @param userGroupResourceBean
	 */
	public FilterBoundSqlUtil(List<GroupResourceBean> userGroupResourceBean) {
		this.userGroupResourceList = userGroupResourceBean;
	}

	public FilterBoundSqlUtil(Map<String,List<String>> dataPrivilegeMap) {
		this.dataPrivilegeMap = dataPrivilegeMap;
	}

	public FilterBoundSqlUtil(List<GroupResourceBean> userGroupResourceBean,Map<String,List<String>> dataPrivilegeMap) {
		this.userGroupResourceList = userGroupResourceBean;
		this.dataPrivilegeMap = dataPrivilegeMap;
	}

	private static final Logger LOG = LoggerFactory.getLogger(FilterBoundSqlUtil.class);

	//普通sql验证
	//private static final String EXAMPLE_SQL= "SELECT   project_id, project_name AS t, spec_id AS s, org_id FROM  tdw_project_relationship";

	//指标sql验证
	//private static final String EXAMPLE_SQL="  select  tpi.DESIGN_INVEST as totalinvest, tpr.org_id from   TDW_PROJECT_RELATIONSHIP tpr, TDW_PROJECT_INVEST tpi WHERE   1 = 1 AND TPI.PROJECT_ID = TPR.PROJECT_ID GROUP BY   tpr.org_id";

	private static final String EXAMPLE_SQL = "SELECT   dataIndex1 as dataindex0," +
																		"           dataIndex2 as dataindex1," +
																		"           dataIndex5 as dataIndex2," +  //org_id
																		"           dataIndex6 as dataIndex3," +
																		"           dataIndex3 as dataIndex4," + //spec_id
																		"           dataIndex4 as dataindex5" +
																		"    FROM   v_20190828134840" +
																		"   WHERE   1 = 1 " +
																		"GROUP BY   dataIndex1," +
																		"           dataIndex2," +
																		"           dataIndex5," +
																		"           dataIndex6," +
																		"           dataIndex3," +
																		"           dataIndex4";


	private static String EXAMPLE_SQL1 = "SELECT dataIndex9 as dataIndex9,dataIndex2 as dataIndex2 FROM v_20190828134840 where 1=1 ";
	/** 用户数据组资源包 */
	private List<GroupResourceBean> userGroupResourceList = new ArrayList<GroupResourceBean>();

	/** 数据包列权限 */
	private Map<String,List<String>> dataPrivilegeMap = new HashMap<String,List<String>>();

	/** 有权限的列 */
	private List<String> privilegeColList = new ArrayList<String>();

	/** 当前列名 有别名存别名 */
	private static List<String> columnsList= new ArrayList<String>();

	private Dialect resDialect = new OracleBoundsDialect();


	/**
	 *
	 * Title: filterBoundSql
	 * Description: 权限过滤
	 * 先数据列权限过滤，在过滤组织与专业
	 * 当org_id或spec_id无权限访问时，并不会做行过滤
	 * @param boundSql
	 * @return
	 */
	private String filterBoundSql(String boundSql) throws Exception {
		if (StringUtil.isNotEmpty(boundSql)) {
			boundSql = boundSql.toLowerCase();
		}else {
			return "";
		}

		//处理数据包列权限
		LOG.debug("待处理列的SQL:" + boundSql);
		String filteredSql = filterSelect(boundSql);

		//处理数据包资源权限
		filteredSql = filterResource(filteredSql);

		return filteredSql;
	}

	/**
	 * Title: filterSelect
	 * Description: 过滤列的权限
	 * @param sql
	 * @return
	 */
	private String filterSelect(String sql) throws Exception {
		//如果当前权限字段一个访问权限都没v1.0版默认报错，页面处理后显示暂无数据
		List<String> privilegeColList = beforeFilterCol(sql);
		if(privilegeColList.isEmpty()) { return ""; }

		//获取当前SQL列
		String subSql = sql.substring(sql.indexOf("select")+6, sql.indexOf("from")).toLowerCase();
		LOG.debug("需格式化的列名:" + subSql);

		String[] colmnsInfo = subSql.split(",");
		StringBuilder filtedColmns = new StringBuilder();
		for (int i = 0; i < colmnsInfo.length; i++) {
			//字段名或别名获取
			String columnName = colmnsInfo[i];
			String checkColName=columnName;

			if (columnName.indexOf("as") != -1) {
				String[] asName = columnName.split("as");
				checkColName = asName[1];
			}

			//TODO  后续需改造成只收集资源KeyId关键字段，无关字段不需要
			//查询字段收集
			columnsList.add(checkColName);

			//判断当前字段是否有数据列权限
			if(isExistsCol(checkColName.trim())) {
					filtedColmns.append(" ").append(columnName).append(",");
			}
		}

		String filterCol = filtedColmns.toString();
		if (filterCol.length() > 0) {
			filterCol = filterCol.substring(0, filterCol.length()-1)+" ";
		}

		return sql.replace(subSql, filterCol);
	}

	/**
	 * Title: getPrivilegeCol
	 * Description: 获取当前用户有的数据权限
	 * @return
	 */
	private List<String> beforeFilterCol(String boundSql) {
		//TODO 通过权限类获取当前用户访问的表权限
		String tableName = getTable(boundSql);

		privilegeColList = dataPrivilegeMap.get(tableName);

		LOG.debug("有权限的字段:" + privilegeColList.toString());
		return privilegeColList;
	}

	/**
	 * Title: isExistsCol
	 * Description: 权限是否允许访问该字段
	 * @param columnName
	 * @return
	 */
	private boolean isExistsCol(String columnName) {
		if(privilegeColList==null||privilegeColList.isEmpty()) { return false; }

		for(String colName:privilegeColList) {
			if(colName.equals(columnName)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Title: filterResource
	 * Description: 过滤数据资源
	 * @param boundSql
	 * @return
	 */
	private String filterResource(String boundSql) {
		if (columnsList == null || columnsList.isEmpty()) { return boundSql; }

//		for (String colName : privilegeColList) {
//			for (GroupResourceBean mGroupResourceBean : userGroupResourceList) {
//				if (colName.toLowerCase().equals(mGroupResourceBean.getKeyId())) {
//					boundSql = resDialect.getResourceSql(boundSql, mGroupResourceBean);
//				}
//			}
//		}

		for (GroupResourceBean mGroupResourceBean : userGroupResourceList) {
			boundSql = resDialect.getResourceSql(boundSql, mGroupResourceBean);
		}

		return boundSql;
	}

	/**
	 * Title: initExampleData
	 * Description:初始化有权限的案例字段,这些都需要从权限中获取
	 */
	private void initExampleData() {
		//初始化权限数据字段
		List<String> privilegeColList = new ArrayList<String>();
//		privilegeColList.add("dataindex0");
		privilegeColList.add("dataindex2");
		privilegeColList.add("dataindex9");
		dataPrivilegeMap.put("v_20190828134840", privilegeColList);

		//初始化资源组织信息
		GroupResourceBean orgResourceBean = new GroupResourceBean();
		orgResourceBean.setResFilterType("treedown");
		orgResourceBean.setResType("ORG");
		orgResourceBean.setResId("0");
		orgResourceBean.setKeyId("dataindex2");
//		userGroupResourceList.add(orgResourceBean);

//		GroupResourceBean mResourceBean = new GroupResourceBean();
//		mResourceBean.setResFilterType("treedown");
//		mResourceBean.setResType("SPEC");
//		mResourceBean.setResId("0");
//		mResourceBean.setKeyId("dataindex4");

		//indata的权限类型
		GroupResourceBean mResourceBean = new GroupResourceBean();
		mResourceBean.setResFilterType("indata");
		mResourceBean.setResType("SPEC");
		mResourceBean.setResIds("'1001','1005'");
		mResourceBean.setKeyId("dataindex2");
		userGroupResourceList.add(mResourceBean);
	}

	/**
	 * Title: main
	 * Description: 测试类
	 * @param args
	 */
	public static void main(String[] args) throws Exception{
		FilterBoundSqlUtil fsu = new FilterBoundSqlUtil();
		fsu.initExampleData();

		String filteredSql = fsu.filterBoundSql(EXAMPLE_SQL1);
		LOG.debug("处理后的SQL:"+filteredSql);

//		fsu.getTable(exampleSql);
	}

	private String getTable(String boundSql) {
		String tableName = boundSql.substring(boundSql.indexOf("from")+4, boundSql.indexOf("where"));
		LOG.debug("截取的表名:"+tableName.trim());
		return tableName.trim();
	}

}
